package com.x.compute.common.function;

import cn.hutool.core.util.StrUtil;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorBoolean;
import com.googlecode.aviator.runtime.type.AviatorJavaType;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorType;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * 包含函数，判断arg2中是否包含arg1，返回boolean类型
 * 函数示例：FIND(arg1, arg2)
 * arg1-字符串类型，arg2-字符串/集合类型
 *
 * @author xuxin
 */
public class FindFunction extends AbstractFunction {

    @Override
    public String getName() {
        return "FIND";
    }

    /**
     * 函数处理逻辑
     *
     * @param env  变量上下文
     * @param arg1 变量1
     * @param arg2 变量2
     * @return
     */
    @Override
    public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
        Object value = arg1.getValue(env);
        String valueString = value == null && arg1.getAviatorType() == AviatorType.JavaType ? ((AviatorJavaType) arg1).getName() : Optional.ofNullable(value).map(obj -> obj.toString()).orElse("");
        Object data = arg2.getValue(env);
        String finalValueString = StrUtil.trim(valueString);
        if (data instanceof String) {
            return AviatorBoolean.valueOf(((String) data).contains(valueString));
        } else if (data instanceof List) {
            return AviatorBoolean.valueOf(((List) data).stream().anyMatch(obj -> obj.toString().contains(finalValueString)));
        } else if (data instanceof Set) {
            return AviatorBoolean.valueOf(((Set) data).stream().anyMatch(obj -> obj.toString().contains(finalValueString)));
        } else if (data instanceof Map) {
            return AviatorBoolean.valueOf(((Map) data).values().stream().anyMatch(obj -> obj.toString().contains(finalValueString)));
        }
        return AviatorBoolean.FALSE;
    }

}
